package br.unifor.cct.mia.coevolution.evaluate.util;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import br.unifor.cct.mia.coevolution.InvalidTypeException;
import br.unifor.cct.mia.coevolution.memory.MemoryIndividual;
import br.unifor.cct.mia.coevolution.memory.SharedMemory;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.GenotypeConverter;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.dataenhancement.Tuple;
import br.unifor.cct.mia.evolutionary.SpeciesConstants;

public class FullConverter {
	
	public File convert(String fileName, Structure strucOriginal, Database dbOriginal, 
									SharedMemory memory, Tuple tuples , List positions, int nBits) throws IOException, InvalidTypeException {
		
		List list = memory.getElements();
		Iterator iterator = list.iterator();
		
		Structure strucResult = strucOriginal;
		Database dbResult = dbOriginal;
		
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			
			if ( specieType == SpeciesConstants.MISSING_VALUE ) {
				Object[] result = MissingValueConverter.convert(strucResult,dbResult,element.getIndividual(),positions,tuples);
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];				
				dbOriginal = (Database)result[1];
				break;
			}
		}
		
		iterator = list.iterator();
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			
			if ( specieType == SpeciesConstants.FEATURE_SELECTION ) {
				Object[] result = FeatureSelectionConverter.convert(strucResult,dbResult,element.getIndividual());
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];
				break;
			}
		}
		
		iterator = list.iterator();
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			nBits=element.getNBits();
			
			if ( specieType == SpeciesConstants.HUGE_SCALE_FEATURE_SELECTION ) {
				Object[] result = HugeScaleFeatureSelectionConverter.convert(strucResult,dbResult,element.getIndividual(),nBits);
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];
				break;
			}
		}
		
		iterator = list.iterator();
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			
			if ( specieType == SpeciesConstants.FEATURE_CONSTRUCTION ) {
				Object[] result = FeatureConstructionConverter.convert(dbOriginal,strucResult,dbResult,element.getIndividual());
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];
				break;
			}
		}	
		
		iterator = list.iterator();
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			
			if ( specieType == SpeciesConstants.INSTANCE_SELECTION ) {
				Object[] result = InstanceSelectionConverter.convert(strucResult,dbResult,element.getIndividual());
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];
				break;
			}
		}		
		
		iterator = list.iterator();
		while( iterator.hasNext() ) {
			MemoryIndividual element = (MemoryIndividual)iterator.next();			
			int specieType = element.getSpecieType();
			
			if ( specieType == SpeciesConstants.INSTANCE_SELECTION_FS ) {
				Object[] result = InstanceSelectionFixedSizeConverter.convert(strucResult,dbResult,element.getIndividual());
				strucResult = (Structure)result[0];
				dbResult = (Database)result[1];
				break;
			}
		}	
		
		GenotypeConverter converter = new GenotypeConverter();
		File resultFileFinal = converter.fullConvert(fileName, strucResult,dbResult);
		
		return resultFileFinal;
	}	
	
}
